package com.mtoolkit.socket.transocder;

import java.io.IOException;
import java.util.Arrays;

import com.mtoolkit.util.ConversionUtil;

public class TranscoderUtil {
	
	private TranscoderUtil() {
	}
	
	public static final byte[] HEAD = new byte[]{
		(byte) 252, (byte) 253, (byte) 254, (byte) 255
	};

	public static final byte[] TAIL = new byte[]{
		(byte) 255, (byte) 254, (byte) 253, (byte) 252
	};
	
	/* 
	 * +-------------------+-------------------+-------------------+-------------------+
	 * |       HEAD        |       LENGTH      |     CONTENT       |       TAIL        |
	 * +-------------------+-------------------+-------------------+-------------------+
	 * |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |
	 * +-------------------+-------------------+-------------------+-------------------+
	 */
	public static byte[] object2Bytes(Object value) throws IOException {
		byte[] content = ConversionUtil.object2Bytes(value);
		byte[] length  = ConversionUtil.int2Bytes(content.length);
		
		byte[] result = new byte[HEAD.length + length.length + content.length + TAIL.length];
		System.arraycopy(HEAD, 0, result, 0, HEAD.length);
		System.arraycopy(length, 0, result,HEAD.length, length.length);
		System.arraycopy(content, 0, result, HEAD.length + length.length, content.length);
		System.arraycopy(TAIL, 0, result, HEAD.length + length.length + content.length, TAIL.length);
		
		return result;
	}
	
	public static <T> T bytes2Object(byte[] value) throws IOException, ClassNotFoundException {
		if (value.length < HEAD.length + 4 + TAIL.length) {
			return null;
		}
		if (!Arrays.equals(HEAD, Arrays.copyOfRange(value, 0, 4))) {
			return null;
		}
		int length = ConversionUtil.bytes2Int(Arrays.copyOfRange(value, 4, 8));
		if (length < 0 || (length != (value.length - HEAD.length - 4 - TAIL.length))) {
			return null;
		}
		if (!Arrays.equals(TAIL, Arrays.copyOfRange(value, value.length - 4, value.length))) {
			return null;
		}
		
		byte[] result = Arrays.copyOfRange(value, HEAD.length + 4, value.length - TAIL.length);
		return ConversionUtil.bytes2Object(result);
	}

}
